//UPD回射服务器，xiaojie ,20201123

#include "glog/logging.h"
#include <iostream>
#include <iostream>
#include <sys/socket.h>     //socket,bind, socklen_t
#include <netinet/in.h>     //sockaddr_in
#include <errno.h>          //errno
#include <string.h>         //strerror
#include <unistd.h>         //read,write, close
#include <arpa/inet.h>      //inet_ntop
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>          //snprintf
#include <syslog.h>
#include <boost/format.hpp>

//UDP服务器，主要功能：
//1.作为守护进程运行
//2.用syslog写日志

using namespace std;

//服务器端口号
const int port = 5588;

void DaemonProcess()
{
    
}

int main(int argc, char** argv)
{
    boost::format fmt;
    string msg;

    //创建守护进程
    DaemonProcess();

    //初始化日志文件
    openlog("udpserver",LOG_CONS|LOG_PID,0);

    char charErr[768] = {0x00};
    syslog(LOG_INFO,"UDP 反射服务器启动成功");

    //创建套接字
    int serverFd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == serverFd)
    {
        snprintf(charErr,sizeof(charErr),"套接口创建失败");
        syslog(LOG_ERR,charErr);
        return -1;
    }

    sockaddr_in serverAddr;
    bzero(&serverAddr,sizeof(serverAddr));
    serverAddr.sin_port = htons(port);                     //端口号
    serverAddr.sin_family = AF_INET;                       //IPv4地址
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);        //不指定IP地址
    socklen_t socklen =sizeof(serverAddr);
    if((bind(serverFd,(sockaddr*)&serverAddr,socklen)) < 0)
    {
        snprintf(charErr,sizeof(charErr),"绑定端口[%d]失败，错误码[%d]，原因:%s"
            ,port,errno,strerror(errno));
        syslog(LOG_ERR,charErr);
        close(serverFd);
    }
    else
    {
        sockaddr_in clientAddr;
        socklen_t clientlen = sizeof(clientAddr);
        char recvSendBuf[512] = {0x00};
        int recvSendLen = 0;
        char clientIP[32] = {0x00};
        int clientPort = 0;
        syslog(LOG_ERR,"开始监听连接");

        //循环监听
        while(true)
        {
            bzero(recvSendBuf,sizeof(recvSendBuf));
            if((recvSendLen = recvfrom(serverFd,recvSendBuf,512,0,(sockaddr*)&clientAddr,&clientlen)) > 0)
            {
                clientPort = ntohs(clientAddr.sin_port);
                inet_ntop(AF_INET, &clientAddr.sin_addr,clientIP,sizeof(clientIP)); 
                snprintf(charErr,sizeof(charErr),"数据接受成功，客户端[%s:%d]，数据：%s"
                      ,clientIP,port,recvSendBuf);
                syslog(LOG_INFO,charErr);

                //回发数据
                if((recvSendLen = sendto(serverFd,recvSendBuf,recvSendLen,0,
                (sockaddr*)&clientAddr,socklen)) == -1)
                {
                    snprintf(charErr,sizeof(charErr),"数据发送失败，目标[%s:%d]，错误码[%d]，原因:%s"
                      ,clientIP,port,errno,strerror(errno));
                    syslog(LOG_ERR,charErr);
                }
                else
                {
                    snprintf(charErr,sizeof(charErr),"数据发送成功，目标[%s:%d]，内容:%s"
                      ,clientIP,clientPort,recvSendBuf);
                    syslog(LOG_INFO,charErr);                   
                }
            }  
            else
            {
               syslog(LOG_ERR,"数据接收失败");             
            }                                  
        }
    }
}